/*********************************************************************************/
/*                                                                               */
/*      ICU Driver                                                               */
/*                                                                               */
/*      Last updated by:   CBS                                                   */
/*      Last update date:  2013/3/1                                              */
/*      Revision:          0                                                     */
/*      Copyright:         DENSO                                                 */
/*                                                                               */
/*********************************************************************************/

/*********************************************************************************/
/*  include files                                                                */
/*********************************************************************************/
#include "MPC5674F_MVx264.h"
#include "IntcInterrupts.h"
#include "Icu.h"

/*********************************************************************************/
/*  prototypes                                                                   */
/*********************************************************************************/
static void Icu_IsrResponseChannel0(void);
static void Icu_IsrResponseChannel1(void);
static void Icu_IsrResponseChannel2(void);
static void Icu_IsrResponseChannel3(void);
static void Icu_IsrResponseChannel4(void);
static void Icu_IsrResponseChannel5(void);
static void Icu_IsrResponseChannel6(void);
static void Icu_IsrResponseChannel7(void);
static void Icu_IsrResponseChannel8(void);
static void Icu_IsrResponseChannel9(void);
static void Icu_IsrResponseChannel10(void);
static void Icu_IsrResponseChannel11(void);
static void Icu_IsrResponseChannel12(void);
static void Icu_IsrResponseChannel13(void);
static void Icu_IsrResponseChannel14(void);
static void Icu_IsrResponseChannel15(void);
static void Icu_IsrResponseChannel16(void);
static void Icu_IsrResponseChannel17(void);
static void Icu_IsrResponseChannel18(void);
static void Icu_IsrResponseChannel19(void);
static void Icu_IsrResponseChannel20(void);
static void Icu_IsrResponseChannel21(void);
static void Icu_IsrResponseChannel22(void);
static void Icu_IsrResponseChannel23(void);
static void Icu_IsrResponseChannel24(void);
static void Icu_IsrResponseChannel25(void);
static void Icu_IsrResponseChannel26(void);
static void Icu_IsrResponseChannel27(void);
static void Icu_IsrResponseChannel28(void);
static void Icu_IsrResponseChannel29(void);
static void Icu_IsrResponseChannel30(void);
static void Icu_IsrResponseChannel31(void);
static Std_ReturnType Icu_CheckInit(const Icu_ConfigType* ConfigPtr);
static Std_ReturnType Icu_CheckStartSignalMeasurement(Icu_ChannelType Channel);
static Std_ReturnType Icu_CheckStopSignalMeasurement(Icu_ChannelType Channel);
static Std_ReturnType Icu_CheckGetTimeElapsed(Icu_ChannelType Channel);
static Std_ReturnType Icu_CheckGetDutyCycleValues(Icu_ChannelType Channel, Icu_DutyCycleType* DutyCycleValues);
static Std_ReturnType Icu_CheckGetVersionInfo(Std_VersionInfoType* versioninfo);
void Det_ReportError(U2 a, U1 b, U1 c, U1 d);

/*********************************************************************************/
/*  defines / data types / structs / unions / macros                             */
/*********************************************************************************/
#define EMIOS_MODE_GPIO 0x00
#define EMIOS_MODE_SAIC 0x02

/* Vector Number */
#define INTC_EMIOS_CHANNEL_0 51
#define INTC_EMIOS_CHANNEL_1 52
#define INTC_EMIOS_CHANNEL_2 53
#define INTC_EMIOS_CHANNEL_3 54
#define INTC_EMIOS_CHANNEL_4 55
#define INTC_EMIOS_CHANNEL_5 56
#define INTC_EMIOS_CHANNEL_6 57
#define INTC_EMIOS_CHANNEL_7 58
#define INTC_EMIOS_CHANNEL_8 59
#define INTC_EMIOS_CHANNEL_9 60
#define INTC_EMIOS_CHANNEL_10 61
#define INTC_EMIOS_CHANNEL_11 62
#define INTC_EMIOS_CHANNEL_12 63
#define INTC_EMIOS_CHANNEL_13 64
#define INTC_EMIOS_CHANNEL_14 65
#define INTC_EMIOS_CHANNEL_15 66
#define INTC_EMIOS_CHANNEL_16 202
#define INTC_EMIOS_CHANNEL_17 203
#define INTC_EMIOS_CHANNEL_18 204
#define INTC_EMIOS_CHANNEL_19 205
#define INTC_EMIOS_CHANNEL_20 206
#define INTC_EMIOS_CHANNEL_21 207
#define INTC_EMIOS_CHANNEL_22 208
#define INTC_EMIOS_CHANNEL_23 209
#define INTC_EMIOS_CHANNEL_24 459
#define INTC_EMIOS_CHANNEL_25 460
#define INTC_EMIOS_CHANNEL_26 461
#define INTC_EMIOS_CHANNEL_27 462
#define INTC_EMIOS_CHANNEL_28 463
#define INTC_EMIOS_CHANNEL_29 464
#define INTC_EMIOS_CHANNEL_30 465
#define INTC_EMIOS_CHANNEL_31 466

/*********************************************************************************/
/*  constants                                                                    */
/*********************************************************************************/
/* Pointer to configuration structure */
static const Icu_ConfigType* IcuConfigPtr;

/*********************************************************************************/
/*  variables                                                                    */
/*********************************************************************************/
typedef enum
{
    ICU_UNINIT,
    ICU_INIT
}Icu_StateType;

typedef enum
{
    ICU_INITIAL_LEVEL_UNKNOW,
    ICU_INITIAL_LEVEL_HIGH,
    ICU_INITIAL_LEVEL_LOW
}Icu_InitialLevelValueType;

typedef enum
{
    ICU_SAMPLE_1,
    ICU_SAMPLE_2,
    ICU_SAMPLE_3,
    ICU_SAMPLE_4
}Icu_SampleType;

typedef struct
{
    Icu_InitialLevelValueType InitialLevelValue;
    Icu_ValueType Sample1;
    Icu_ValueType Sample2;
    Icu_ValueType Sample3;
    Icu_ValueType Sample4;
    Icu_SampleType WaitToSample;
}Icu_DataType;

#if (ICU_GET_VERSION_INFO_API == STD_ON)
static Std_VersionInfoType ICU_VersionInfo =
{
    ICU_VENDOR_ID, 
    MODULE_ID_ICU,
    ICU_INSTANCE_ID,
    ICU_SW_MAJOR_VERSION,
    ICU_SW_MINOR_VERSION,
    ICU_SW_PATCH_VERSION,
    ICU_AR_MAJOR_VERSION,
    ICU_AR_MINOR_VERSION,
    ICU_AR_PATCH_VERSION 
};
#endif  /* ICU_GET_VERSION_INFO_API */

Icu_DataType IcuData[32];

static Icu_StateType icuState = ICU_UNINIT;

/*********************************************************************************/
/*  API Functions                                                                */
/*********************************************************************************/

/***************************************************************************************************/
/*  Service name    :   Icu_Init                                                                   */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Non Reentrant                                                              */
/*  Parameters (in) :   Pointer to ICU driver configuration.                                       */
/*  Return value    :   None                                                                       */
/*  Discription     :   This function initializes the driver.                                      */
/***************************************************************************************************/
void Icu_Init(const Icu_ConfigType* ConfigPtr)
{
    Icu_ChannelType channel;
    Icu_HwChannelNumber HwChannel;

    if(E_OK == Icu_CheckInit(ConfigPtr))
    {
        IcuConfigPtr = ConfigPtr;

        EMIOS.MCR.B.MDIS = 0;
        EMIOS.MCR.B.FRZ = 1;
        EMIOS.MCR.B.GPRE = IcuConfigPtr->GlobalPrescalerBits;
        EMIOS.MCR.B.GPREN = 1;
        EMIOS.MCR.B.GTBE = 1;

        for(channel = ICU_CH0;channel < IcuConfigPtr->NbrOfChannels;channel++)
        {
            HwChannel = IcuConfigPtr->IcuChannelConfig[channel].IcuHwChannelNumber;

            EMIOS.CH[HwChannel].CCR.B.FREN = 1;
            EMIOS.CH[HwChannel].CCR.B.UCPRE = IcuConfigPtr->IcuChannelConfig[channel].IcuChannelPrescalerBits;
            EMIOS.CH[HwChannel].CCR.B.UCPREN = 1;
            EMIOS.CH[HwChannel].CCR.B.DMA = 0;
            EMIOS.CH[HwChannel].CCR.B.FEN = 1;
            EMIOS.CH[HwChannel].CCR.B.BSL = 3;
            EMIOS.CH[HwChannel].CCR.B.EDSEL = 1;

            switch(HwChannel)
            {
                case 0:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel0,INTC_EMIOS_CHANNEL_0,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 1:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel1,INTC_EMIOS_CHANNEL_1,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 2:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel2,INTC_EMIOS_CHANNEL_2,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 3:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel3,INTC_EMIOS_CHANNEL_3,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 4:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel4,INTC_EMIOS_CHANNEL_4,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 5:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel5,INTC_EMIOS_CHANNEL_5,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 6:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel6,INTC_EMIOS_CHANNEL_6,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 7:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel7,INTC_EMIOS_CHANNEL_7,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 8:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel8,INTC_EMIOS_CHANNEL_8,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 9:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel9,INTC_EMIOS_CHANNEL_9,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 10:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel10,INTC_EMIOS_CHANNEL_10,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 11:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel11,INTC_EMIOS_CHANNEL_11,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 12:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel12,INTC_EMIOS_CHANNEL_12,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 13:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel13,INTC_EMIOS_CHANNEL_13,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 14:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel14,INTC_EMIOS_CHANNEL_14,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 15:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel15,INTC_EMIOS_CHANNEL_15,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 16:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel16,INTC_EMIOS_CHANNEL_16,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 17:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel17,INTC_EMIOS_CHANNEL_17,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 18:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel18,INTC_EMIOS_CHANNEL_18,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 19:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel19,INTC_EMIOS_CHANNEL_19,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 20:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel20,INTC_EMIOS_CHANNEL_20,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 21:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel21,INTC_EMIOS_CHANNEL_21,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 22:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel22,INTC_EMIOS_CHANNEL_22,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 23:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel23,INTC_EMIOS_CHANNEL_23,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 24:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel24,INTC_EMIOS_CHANNEL_24,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 25:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel25,INTC_EMIOS_CHANNEL_25,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 26:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel26,INTC_EMIOS_CHANNEL_26,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 27:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel27,INTC_EMIOS_CHANNEL_27,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 28:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel28,INTC_EMIOS_CHANNEL_28,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 29:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel29,INTC_EMIOS_CHANNEL_29,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 30:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel30,INTC_EMIOS_CHANNEL_30,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                case 31:
                    INTC_InstallINTCInterruptHandler(Icu_IsrResponseChannel31,INTC_EMIOS_CHANNEL_31,IcuConfigPtr->IcuChannelConfig[channel].IcuInterruptPriority);
                    break;
                default:
                    break;
            }
        }

        icuState = ICU_INIT;
    }
}

/***************************************************************************************************/
/*  Service name    :   Icu_DeInit                                                                 */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Non Reentrant                                                              */
/*  Parameters (in) :   None                                                                       */
/*  Return value    :   None                                                                       */
/*  Discription     :   This function de-initializes the ICU module.                               */
/***************************************************************************************************/
#if(ICU_DE_INIT_API == STD_ON)  /* ICU092 ICU301 */
void Icu_DeInit(void)
{
    Icu_ChannelType channel;
    Icu_HwChannelNumber HwChannel;

    IcuConfigPtr = (Icu_ConfigType*)0;

    EMIOS.MCR.B.MDIS = 0;
    EMIOS.MCR.B.FRZ = 0;
    EMIOS.MCR.B.GPRE = 0;
    EMIOS.MCR.B.GPREN = 0;
    EMIOS.MCR.B.GTBE = 0;

    for(channel = ICU_CH0;channel < IcuConfigPtr->NbrOfChannels;channel++)
    {
        HwChannel = IcuConfigPtr->IcuChannelConfig[channel].IcuHwChannelNumber;

        EMIOS.CH[HwChannel].CCR.B.FREN = 0;
        EMIOS.CH[HwChannel].CCR.B.UCPRE = 0;
        EMIOS.CH[HwChannel].CCR.B.UCPREN = 0;
        EMIOS.CH[HwChannel].CCR.B.DMA = 0;
        EMIOS.CH[HwChannel].CCR.B.FEN = 0;
        EMIOS.CH[HwChannel].CCR.B.BSL = 0;
        EMIOS.CH[HwChannel].CCR.B.EDSEL = 0;
    }

    icuState = ICU_UNINIT;
}
#endif  /* ICU_DE_INIT_API */

/***************************************************************************************************/
/*  Service name    :   Icu_StartSignalMeasurement                                                 */
/*  Sync/Async      :   Asynchronous                                                               */
/*  Reentrancy      :   Reentrant                                                                  */
/*  Parameters (in) :   Channel  Numeric identifier of the ICU channel.                            */
/*  Return value    :   None                                                                       */
/*  Discription     :   This function starts the measurement of signals.                           */
/***************************************************************************************************/
#if(ICU_SIGNAL_MEASUREMENT_API == STD_ON)  /* ICU142 ICU335 */
void Icu_StartSignalMeasurement(Icu_ChannelType Channel)
{
    Icu_HwChannelNumber HwChannel;

    if(E_OK == Icu_CheckStartSignalMeasurement(Channel))
    {
        HwChannel = IcuConfigPtr->IcuChannelConfig[Channel].IcuHwChannelNumber;

        IcuData[HwChannel].InitialLevelValue = ICU_INITIAL_LEVEL_UNKNOW;
        IcuData[HwChannel].Sample1 = 0;
        IcuData[HwChannel].Sample2 = 0;
        IcuData[HwChannel].Sample3 = 0;
        IcuData[HwChannel].Sample4 = 0;
        IcuData[HwChannel].WaitToSample = ICU_SAMPLE_1;

        EMIOS.CH[HwChannel].CCR.B.MODE = EMIOS_MODE_SAIC;
    }
}
#endif  /* ICU_SIGNAL_MEASUREMENT_API */

/***************************************************************************************************/
/*  Service name    :   Icu_StopSignalMeasurement                                                  */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Reentrant                                                                  */
/*  Parameters (in) :   Channel  Numeric identifier of the ICU channel.                            */
/*  Return value    :   None                                                                       */
/*  Discription     :   This function stops the measurement of signals of the given channel.       */
/***************************************************************************************************/
#if(ICU_SIGNAL_MEASUREMENT_API == STD_ON)  /* ICU145 ICU337 */
void Icu_StopSignalMeasurement(Icu_ChannelType Channel)
{
    if(E_OK == Icu_CheckStopSignalMeasurement(Channel))
    {
        EMIOS.CH[IcuConfigPtr->IcuChannelConfig[Channel].IcuHwChannelNumber].CCR.B.MODE = EMIOS_MODE_GPIO;
    }
}
#endif  /* ICU_SIGNAL_MEASUREMENT_API */

/***************************************************************************************************/
/*  Service name    :   Icu_GetTimeElapsed                                                         */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Reentrant                                                                  */
/*  Parameters (in) :   Channel  Numeric identifier of the ICU channel.                            */
/*  Return value    :   Icu_ValueType                                                              */
/*  Discription     :   This function reads the elapsed Signal Low Time for the given channel.     */
/***************************************************************************************************/
#if(ICU_GET_TIME_ELAPSED_API == STD_ON)  /* ICU105 ICU341 */
Icu_ValueType Icu_GetTimeElapsed(Icu_ChannelType Channel)
{
    Icu_ValueType returnValue = 0;
    Icu_HwChannelNumber HwChannel;
    U1 CleanData;

    CleanData = 0;

    if(E_OK == Icu_CheckGetTimeElapsed(Channel))
    {
        HwChannel = IcuConfigPtr->IcuChannelConfig[Channel].IcuHwChannelNumber;

        if(IcuConfigPtr->IcuChannelConfig[Channel].IcuSignalMeasurementProperty == ICU_ACTIVE_TIME)
        {
            if(IcuData[HwChannel].InitialLevelValue != ICU_INITIAL_LEVEL_UNKNOW)
            {
                if(IcuData[HwChannel].Sample2 != 0)
                {
                    if(IcuData[HwChannel].Sample2 > IcuData[HwChannel].Sample1)
                    {
                        returnValue = IcuData[HwChannel].Sample2 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample2 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    CleanData = 1;
                }
                else
                {
                    returnValue = 0;
                }
            }
        }
        else if(IcuConfigPtr->IcuChannelConfig[Channel].IcuSignalMeasurementProperty == ICU_HIGH_TIME)
        {
            if(IcuData[HwChannel].InitialLevelValue == ICU_INITIAL_LEVEL_HIGH)
            {
                if(IcuData[HwChannel].Sample2 != 0)
                {
                    if(IcuData[HwChannel].Sample2 > IcuData[HwChannel].Sample1)
                    {
                        returnValue = IcuData[HwChannel].Sample2 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample2 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    CleanData = 1;
                }
                else
                {
                    returnValue = 0;
                }
            }
            else
            {
                CleanData = 1;
            }
        }
        else if(IcuConfigPtr->IcuChannelConfig[Channel].IcuSignalMeasurementProperty == ICU_LOW_TIME)
        {
            if(IcuData[HwChannel].InitialLevelValue == ICU_INITIAL_LEVEL_LOW)
            {
                if(IcuData[HwChannel].Sample2 != 0)
                {
                    if(IcuData[HwChannel].Sample2 > IcuData[HwChannel].Sample1)
                    {
                        returnValue = IcuData[HwChannel].Sample2 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample2 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    CleanData = 1;
                }
                else
                {
                    returnValue = 0;
                }
            }
            else
            {
                CleanData = 1;
            }
        }
        else  /* ICU_PERIOD_TIME */
        {
            if(IcuData[HwChannel].InitialLevelValue == ICU_INITIAL_LEVEL_UNKNOW)
            {
                returnValue = 0;
            }
            else if(IcuData[HwChannel].InitialLevelValue == ICU_INITIAL_LEVEL_HIGH)
            {
                if(((IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_BOTH_EDGES)||(IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_RISING_EDGE))&&(IcuData[HwChannel].Sample3 != 0))
                {
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        returnValue = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample3 + 0x00FFFFFF -IcuData[HwChannel].Sample1;
                    }
                    CleanData = 1;
                }
                else if((IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_FALLING_EDGE)&&(IcuData[HwChannel].Sample4 != 0))
                {
                    if(IcuData[HwChannel].Sample4 > IcuData[HwChannel].Sample2)
                    {
                        returnValue = IcuData[HwChannel].Sample4 - IcuData[HwChannel].Sample2;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample4 + 0x00FFFFFF -IcuData[HwChannel].Sample2;
                    }
                    CleanData = 1;
                }
                else
                {
                    returnValue = 0;
                }
            }
            else  /* ICU_INITIAL_LEVEL_LOW */
            {
                if(((IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_BOTH_EDGES)||(IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_FALLING_EDGE))&&(IcuData[HwChannel].Sample3 != 0))
                {
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        returnValue = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample3 + 0x00FFFFFF -IcuData[HwChannel].Sample1;
                    }
                    CleanData = 1;
                }
                else if((IcuConfigPtr->IcuChannelConfig[Channel].IcuDefaultStartEdge == ICU_RISING_EDGE)&&(IcuData[HwChannel].Sample4 != 0))
                {
                    if(IcuData[HwChannel].Sample4 > IcuData[HwChannel].Sample2)
                    {
                        returnValue = IcuData[HwChannel].Sample4 - IcuData[HwChannel].Sample2;
                    }
                    else
                    {
                        returnValue = IcuData[HwChannel].Sample4 + 0x00FFFFFF -IcuData[HwChannel].Sample2;
                    }
                    CleanData = 1;
                }
                else
                {
                    returnValue = 0;
                }

            }
        }

        if(CleanData == 1)
        {
            IcuData[HwChannel].InitialLevelValue = ICU_INITIAL_LEVEL_UNKNOW;
            IcuData[HwChannel].Sample1 = 0;
            IcuData[HwChannel].Sample2 = 0;
            IcuData[HwChannel].Sample3 = 0;
            IcuData[HwChannel].Sample4 = 0;
            IcuData[HwChannel].WaitToSample = ICU_SAMPLE_1;
        }
    }
    else
    {
        returnValue = 0;  /* ICU179 */
    }

    return(returnValue);
}
#endif  /* ICU_GET_TIME_ELAPSED_API */

/***************************************************************************************************************************/
/*  Service name    :   Icu_GetDutyCycleValues                                                                             */
/*  Sync/Async      :   Synchronous                                                                                        */
/*  Reentrancy      :   Reentrant                                                                                          */
/*  Parameters (in) :   Channel  Numeric identifier of the ICU channel.                                                    */
/*  Parameters (out):   DutyCycleValue Pointer to a buffer where the results (high time and period time) shall be placed.  */
/*  Return value    :   None                                                                                               */
/*  Discription     :   This function reads the elapsed Signal Low Time for the given channel.                             */
/***************************************************************************************************************************/
#if(ICU_GET_DUTY_CYCLE_VALUES_API == STD_ON)  /* ICU106 ICU345 */
void Icu_GetDutyCycleValues(Icu_ChannelType Channel,Icu_DutyCycleType* DutyCycleValues)
{
    Icu_HwChannelNumber HwChannel;

    if(E_OK == Icu_CheckGetDutyCycleValues(Channel,DutyCycleValues))
    {
        HwChannel = IcuConfigPtr->IcuChannelConfig[Channel].IcuHwChannelNumber;

        if(IcuData[HwChannel].InitialLevelValue == ICU_INITIAL_LEVEL_LOW)
        {
            switch(IcuData[HwChannel].WaitToSample)
            {
                case ICU_SAMPLE_1:
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample2)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample2;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample2;
                    }
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    break;
                case ICU_SAMPLE_2:
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample4)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample1 - IcuData[HwChannel].Sample4;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF - IcuData[HwChannel].Sample4;
                    }
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample3)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 -IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF - IcuData[HwChannel].Sample3;
                    }
                    break;
                case ICU_SAMPLE_3:
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample4)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample1 - IcuData[HwChannel].Sample4;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF - IcuData[HwChannel].Sample4;
                    }
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample3)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 -IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF - IcuData[HwChannel].Sample3;
                    }
                    break;
                case ICU_SAMPLE_4:
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample2)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample2;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample2;
                    }
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    break;
                default:
                    break;
            }
        }
        else  /* ICU_INITIAL_LEVEL_HIGH */
        {
            switch(IcuData[HwChannel].WaitToSample)
            {
                case ICU_SAMPLE_1:
                    if(IcuData[HwChannel].Sample2 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample2 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample2 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    break;
                case ICU_SAMPLE_2:
                    if(IcuData[HwChannel].Sample4 > IcuData[HwChannel].Sample3)
                   {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample4 - IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample4 + 0x00FFFFFF - IcuData[HwChannel].Sample3;
                    }
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample3)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 - IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF -IcuData[HwChannel].Sample3;
                    }
                    break;
                case ICU_SAMPLE_3:
                    if(IcuData[HwChannel].Sample4 > IcuData[HwChannel].Sample3)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample4 - IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample4 + 0x00FFFFFF - IcuData[HwChannel].Sample3;
                    }
                    if(IcuData[HwChannel].Sample1 > IcuData[HwChannel].Sample3)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 - IcuData[HwChannel].Sample3;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample1 + 0x00FFFFFF -IcuData[HwChannel].Sample3;
                    }
                    break;
                case ICU_SAMPLE_4:
                    if(IcuData[HwChannel].Sample2 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample2 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->ActiveTime = IcuData[HwChannel].Sample2 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    if(IcuData[HwChannel].Sample3 > IcuData[HwChannel].Sample1)
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 - IcuData[HwChannel].Sample1;
                    }
                    else
                    {
                        DutyCycleValues->PeriodTime = IcuData[HwChannel].Sample3 + 0x00FFFFFF - IcuData[HwChannel].Sample1;
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
#endif  /* ICU_GET_DUTY_CYCLE_VALUES_API */

/********************************************************************************************************/
/*  Service name    :   Icu_GetVersionInfo                                                              */
/*  Sync/Async      :   Synchronous                                                                     */
/*  Reentrancy      :   Reentrant                                                                       */
/*  Parameters(out) :   versioninfo   Pointer to where to store the version information of this module. */
/*  Return value    :   None                                                                            */
/*  Discription     :   Return the version information of this module.                                  */
/********************************************************************************************************/
#if(ICU_GET_VERSION_INFO_API == STD_ON)  /* ICU094 ICU347 */
void Icu_GetVersionInfo(Std_VersionInfoType* versioninfo)
{
    if(E_OK == Icu_CheckGetVersionInfo(versioninfo))
    {
        versioninfo->vendorID = ICU_VersionInfo.vendorID;
        versioninfo->moduleID = ICU_VersionInfo.moduleID;
        versioninfo->instanceID = ICU_VersionInfo.instanceID;

        versioninfo->sw_major_version = ICU_VersionInfo.sw_major_version;
        versioninfo->sw_minor_version = ICU_VersionInfo.sw_minor_version;
        versioninfo->sw_patch_version = ICU_VersionInfo.sw_patch_version;

        versioninfo->ar_major_version = ICU_VersionInfo.ar_major_version;
        versioninfo->ar_minor_version = ICU_VersionInfo.ar_minor_version;
        versioninfo->ar_patch_version = ICU_VersionInfo.ar_patch_version;
    }
}
#endif  /* ICU_GET_VERSION_INFO_API */

/*********************************************************************************/
/*    Local Functions                                                            */
/*********************************************************************************/
#define Icu_IsrResponse(_channel)                                              \
static void Icu_IsrResponseChannel##_channel(void)                             \
{                                                                              \
    EMIOS.CH[_channel].CSR.B.FLAG = 1;                                         \
                                                                               \
    switch(IcuData[_channel].WaitToSample)                                     \
    {                                                                          \
        case ICU_SAMPLE_1:                                                     \
            if(EMIOS.CH[_channel].CSR.B.UCIN == 1)                             \
            {                                                                  \
                IcuData[_channel].InitialLevelValue = ICU_INITIAL_LEVEL_HIGH;  \
            }                                                                  \
            else                                                               \
            {                                                                  \
                IcuData[_channel].InitialLevelValue = ICU_INITIAL_LEVEL_LOW;   \
            }                                                                  \
            IcuData[_channel].Sample1 = EMIOS.CH[_channel].CADR.R;             \
            IcuData[_channel].WaitToSample = ICU_SAMPLE_2;                     \
            break;                                                             \
        case ICU_SAMPLE_2:                                                     \
            IcuData[_channel].Sample2 = EMIOS.CH[_channel].CADR.R;             \
            IcuData[_channel].WaitToSample = ICU_SAMPLE_3;                     \
            break;                                                             \
        case ICU_SAMPLE_3:                                                     \
            IcuData[_channel].Sample3 = EMIOS.CH[_channel].CADR.R;             \
            IcuData[_channel].WaitToSample = ICU_SAMPLE_4;                     \
            break;                                                             \
        case ICU_SAMPLE_4:                                                     \
            IcuData[_channel].Sample4 = EMIOS.CH[_channel].CADR.R;             \
            IcuData[_channel].WaitToSample = ICU_SAMPLE_1;                     \
            break;                                                             \
        default:                                                               \
            break;                                                             \
    }                                                                          \
}

Icu_IsrResponse(0)
Icu_IsrResponse(1)
Icu_IsrResponse(2)
Icu_IsrResponse(3)
Icu_IsrResponse(4)
Icu_IsrResponse(5)
Icu_IsrResponse(6)
Icu_IsrResponse(7)
Icu_IsrResponse(8)
Icu_IsrResponse(9)
Icu_IsrResponse(10)
Icu_IsrResponse(11)
Icu_IsrResponse(12)
Icu_IsrResponse(13)
Icu_IsrResponse(14)
Icu_IsrResponse(15)
Icu_IsrResponse(16)
Icu_IsrResponse(17)
Icu_IsrResponse(18)
Icu_IsrResponse(19)
Icu_IsrResponse(20)
Icu_IsrResponse(21)
Icu_IsrResponse(22)
Icu_IsrResponse(23)
Icu_IsrResponse(24)
Icu_IsrResponse(25)
Icu_IsrResponse(26)
Icu_IsrResponse(27)
Icu_IsrResponse(28)
Icu_IsrResponse(29)
Icu_IsrResponse(30)
Icu_IsrResponse(31)

static Std_ReturnType Icu_CheckInit(const Icu_ConfigType* ConfigPtr)
{
    Std_ReturnType returnValue;

#if(ICU_DEV_ERROR_DETECT == STD_ON)
    if(ConfigPtr == (Icu_ConfigType*)0)
    {
        /* ICU023 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_INIT_SERVICE_ID,ICU_E_PARAM_CONFIG);
        returnValue = E_NOT_OK;
    }
    else if(icuState == ICU_INIT)
    {
        /* ICU220 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_INIT_SERVICE_ID,ICU_E_ALREADY_INITIALIZED);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}

#if(ICU_SIGNAL_MEASUREMENT_API == STD_ON)  /* ICU142 ICU335 */
static Std_ReturnType Icu_CheckStartSignalMeasurement(Icu_ChannelType Channel)
{
    Std_ReturnType returnValue;

#if(ICU_DEV_ERROR_DETECT == STD_ON)
    if(!(Channel < IcuConfigPtr->NbrOfChannels))
    {
        /* ICU176 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_STARTSIGNALMEASUREMENT_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else if(!(IcuConfigPtr->IcuChannelConfig[Channel].IcuMeasurementMode == ICU_MODE_SIGNAL_MEASUREMENT))
    {
        /* ICU176 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_STARTSIGNALMEASUREMENT_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* ICU_SIGNAL_MEASUREMENT_API */

#if(ICU_SIGNAL_MEASUREMENT_API == STD_ON)  /* ICU145 ICU337 */
static Std_ReturnType Icu_CheckStopSignalMeasurement(Icu_ChannelType Channel)
{
    Std_ReturnType returnValue;

#if(ICU_DEV_ERROR_DETECT == STD_ON)
    if(!(Channel < IcuConfigPtr->NbrOfChannels))
    {
        /* ICU177 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_STOPSIGNALMEASUREMENT_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else if(!(IcuConfigPtr->IcuChannelConfig[Channel].IcuMeasurementMode == ICU_MODE_SIGNAL_MEASUREMENT))
    {
        /* ICU177 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_STOPSIGNALMEASUREMENT_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* ICU_SIGNAL_MEASUREMENT_API */

#if(ICU_GET_TIME_ELAPSED_API == STD_ON)  /* ICU105 ICU341 */
static Std_ReturnType Icu_CheckGetTimeElapsed(Icu_ChannelType Channel)
{
    Std_ReturnType returnValue;

#if(ICU_DEV_ERROR_DETECT == STD_ON)
    if(!(Channel < IcuConfigPtr->NbrOfChannels))
    {
        /* ICU178 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETTIMEELAPSED_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else if(!(IcuConfigPtr->IcuChannelConfig[Channel].IcuMeasurementMode == ICU_MODE_SIGNAL_MEASUREMENT))
    {
        /* ICU178 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETTIMEELAPSED_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* ICU_GET_TIME_ELAPSED_API */

#if(ICU_GET_DUTY_CYCLE_VALUES_API == STD_ON)  /* ICU106 ICU345 */
static Std_ReturnType Icu_CheckGetDutyCycleValues(Icu_ChannelType Channel, Icu_DutyCycleType* DutyCycleValues)
{
    Std_ReturnType returnValue;

#if(ICU_DEV_ERROR_DETECT == STD_ON)
    if(!(Channel < IcuConfigPtr->NbrOfChannels))
    {
        /* ICU180 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETDUTYCYCLEVALUES_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else if(!(IcuConfigPtr->IcuChannelConfig[Channel].IcuMeasurementMode == ICU_MODE_SIGNAL_MEASUREMENT))
    {
        /* ICU180 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETDUTYCYCLEVALUES_SERVICE_ID,ICU_E_PARAM_CHANNEL);
        returnValue = E_NOT_OK;
    }
    else if(DutyCycleValues == (Icu_DutyCycleType*)0)
    {
        /* ICU181 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETDUTYCYCLEVALUES_SERVICE_ID,ICU_E_PARAM_BUFFER_PTR);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* ICU_GET_DUTY_CYCLE_VALUES_API */

#if(ICU_GET_VERSION_INFO_API == STD_ON)  /* ICU094 ICU347 */
static Std_ReturnType Icu_CheckGetVersionInfo(Std_VersionInfoType* versioninfo)
{
    Std_ReturnType returnValue;

#if( ICU_DEV_ERROR_DETECT == STD_ON )
    if( 0 == versioninfo)
    {
        /* ICU356 */
        Det_ReportError(MODULE_ID_ICU,ICU_INSTANCE_ID,ICU_GETVERSIONINFO_SERVICE_ID,ICU_E_PARAM_VINFO);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* ICU_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* ICU_GET_VERSION_INFO_API */

void Det_ReportError(U2 a, U1 b, U1 c, U1 d)
{

}

/**** End Of File ****************************************************************/